﻿
// MFCCefDlg.cpp: 实现文件
//

#include "pch.h"
#include "framework.h"
#include "MFCCef.h"
#include "MFCCefDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#include <include/internal/cef_win.h>
#include <include/internal/cef_ptr.h>
#include <include/cef_browser.h>
#include <include/cef_app.h>
#include "CCefBrowserEventHandler.h"
#include "include/views/cef_browser_view.h"
#include "CBrowserDlg.h"
#include "obj.h"
#include "CDlgPlatform.h"
#include "CDlgAddAccount.h"
#include "log.h"
CMFCCefDlg::CMFCCefDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_MFCCEF_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMFCCefDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST_ACCOUNT, m_list);
}

BEGIN_MESSAGE_MAP(CMFCCefDlg, CDialogEx)
	//ON_WM_PAINT()
	//ON_WM_QUERYDRAGICON()
	//ON_WM_DESTROY()
	//ON_WM_CLOSE()
	ON_BN_CLICKED(IDC_BUTTON1, &CMFCCefDlg::OnBnClickedButton1)
	ON_WM_DESTROY()
	ON_BN_CLICKED(IDC_BUTTON_ADD_ACCOUNT, &CMFCCefDlg::OnBnClickedButtonAddAccount)
	ON_BN_CLICKED(IDC_BUTTON_ADD_PLATFORM, &CMFCCefDlg::OnBnClickedButtonAddPlatform)
	ON_BN_CLICKED(IDC_BUTTON_START_SEL, &CMFCCefDlg::OnBnClickedButtonStartSel)
	ON_BN_CLICKED(IDC_BUTTON_StopAll, &CMFCCefDlg::OnBnClickedButtonStopall)
	ON_BN_CLICKED(IDC_BUTTON_PauseAll, &CMFCCefDlg::OnBnClickedButtonPauseall)
	ON_BN_CLICKED(IDC_BUTTON_ResumeAll, &CMFCCefDlg::OnBnClickedButtonResumeall)
	ON_BN_CLICKED(IDC_BUTTON_Pause, &CMFCCefDlg::OnBnClickedButtonPause)
	ON_BN_CLICKED(IDC_BUTTON_Stop, &CMFCCefDlg::OnBnClickedButtonStop)
	ON_BN_CLICKED(IDC_BUTTON_Resume, &CMFCCefDlg::OnBnClickedButtonResume)
	ON_BN_CLICKED(IDC_BUTTON_Restart, &CMFCCefDlg::OnBnClickedButtonRestart)
	ON_BN_CLICKED(IDC_BUTTON_StartAll, &CMFCCefDlg::OnBnClickedButtonStartall)
END_MESSAGE_MAP()

extern dmsoft* g_dm;

HWND   g_main_hwnd = NULL;
CMFCCefDlg* g_main_cwnd = NULL;

void UpdateUI(long index, long action)
{
	g_main_cwnd->UpdateList(index, action);
}
// CMFCCefDlg 消息处理程序
void UpdateAction(long index, CString msg)
{
	Log(index, msg);
	g_main_cwnd->UpdateAction(index, msg);
}
int SplitString(LPCTSTR lpszStr, LPCTSTR lpszSplit, CStringArray& rArrString, BOOL bAllowNullString)
{
	rArrString.RemoveAll();
	CString szStr = lpszStr;
	szStr.TrimLeft();
	szStr.TrimRight();

	if (szStr.GetLength() == 0)
	{
		return 0;
	}

	CString szSplit = lpszSplit;

	if (szSplit.GetLength() == 0)
	{
		rArrString.Add(szStr);
		return 1;
	}

	CString s;
	int n;

	do
	{
		n = szStr.Find(szSplit);

		if (n > 0)
		{
			rArrString.Add(szStr.Left(n));
			szStr = szStr.Right(szStr.GetLength() - n - szSplit.GetLength());
			szStr.TrimLeft();
		}
		else if (n == 0)
		{
			if (bAllowNullString)
			{
				rArrString.Add(_T(""));
			}

			szStr = szStr.Right(szStr.GetLength() - szSplit.GetLength());
			szStr.TrimLeft();
		}
		else
		{
			if ((szStr.GetLength() > 0) || bAllowNullString)
			{
				rArrString.Add(szStr);
			}

			break;
		}
	} while (1);

	return (int)rArrString.GetSize();
}
BOOL CMFCCefDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	g_main_hwnd = GetSafeHwnd();
	g_main_cwnd = this;

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时，框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码

	//## cef ##
	/*
	//没啥用抄来的
	const bool use_views = true;
	
	//chrome控件信息类
	CefWindowInfo cefWindowInfo;
	
	CRect crect;
	GetClientRect(crect);
	cefWindowInfo.SetAsChild(GetSafeHwnd(), crect);
	
	CefBrowserSettings browser_settings;
	// CMFCCefDlg 对话框
	CefRefPtr<CCefBrowserEventHandler> cef_handler;
	cef_handler = new CCefBrowserEventHandler(use_views);
	CefBrowserHost::CreateBrowser(cefWindowInfo, cef_handler, "http://play.2144.cn/rxfs/index.html?id=55721&sid=20", browser_settings, nullptr, nullptr);

	//## cef ##
	*/
	//m_list.SetExtendedStyle(m_list.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_INFOTIP | LVS_EX_CHECKBOXES);
	m_list.SetExtendedStyle(m_list.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
	m_list.InsertColumn(0, _T("窗口句柄"), LVCFMT_CENTER, 60);
	m_list.InsertColumn(1, _T("PID"), LVCFMT_LEFT, 0);
	m_list.InsertColumn(2, _T("主线程序号"), LVCFMT_LEFT, 0);
	m_list.InsertColumn(3, _T("副线程序号"), LVCFMT_LEFT, 0);
	m_list.InsertColumn(4, _T("主线程状态"), LVCFMT_CENTER, 75);
	m_list.InsertColumn(5, _T("副线程状态"), LVCFMT_LEFT, 0);
	m_list.InsertColumn(6, _T("任务状态"), LVCFMT_CENTER, 0);
	m_list.InsertColumn(7, _T("异常状态"), LVCFMT_CENTER, 108);
	m_list.InsertColumn(8, _T("角色行为"), LVCFMT_CENTER, 300);
	m_list.InsertColumn(9, _T("平台"), LVCFMT_CENTER, 80);
	m_list.InsertColumn(10, _T("区服"), LVCFMT_CENTER, 40);
	m_list.InsertColumn(11, _T("帐号"), LVCFMT_CENTER, 120);
	m_list.InsertColumn(12, _T("主窗口句柄"), LVCFMT_CENTER, 80);
	
	Load();
	return TRUE;  // 除非将焦点设置到控件，否则返回 TRUE
}

// 如果向对话框添加最小化按钮，则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序，
//  这将由框架自动完成。
/*
void CMFCCefDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}
*/
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
/*
HCURSOR CMFCCefDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}
*/

/*
void CMFCCefDlg::OnDestroy()
{
	CDialogEx::OnDestroy();	
}


void CMFCCefDlg::OnClose()
{
	//CefQuitMessageLoop();
	//cef_handler->CloseAllBrowsers(true);
	//CefShutdown();
	
	CDialogEx::OnClose();
}*/

void CMFCCefDlg::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码	
	//int i = 0, nCount = m_list.GetItemCount();	
	POSITION pos = m_list.GetFirstSelectedItemPosition();
	if (pos == NULL)
	{
		Log(_T("请选择要登陆的帐号"));
		return;
	}
	int i = m_list.GetNextSelectedItem(pos);
	CString szHwnd;
	//while (i < nCount) {
		CString szPlatfrom = m_list.GetItemText(i, 9); // 平台
		CString szRegion = m_list.GetItemText(i, 10); // 平台
		CString szAccount = m_list.GetItemText(i, 11); // 区服
		CBrowserDlg* browser = new CBrowserDlg;
		browser->param = GetPlatfrom(szPlatfrom);
		browser->m_user_name = szAccount;
		browser->m_password = GetAccountPwd(szAccount);
		browser->Create(IDD_BROSWER_DIG, GetDesktopWindow());
		browser->ShowWindow(SW_SHOW);
		szHwnd.Format(L"%ld", (long)browser->GetSafeHwnd());
		m_list.SetItemText(i, 0, szHwnd);
		m_list.SetItemText(i, 12, szHwnd);		
		++i;
	//}
	
}
void CMFCCefDlg::Load() {		
	CFile file;
	if (!file.Open(L"./data/account.data", CFile::modeRead)) {
		//AfxMessageBox(L"加载配置文件出错");
		return;
	}
	m_list.DeleteAllItems();
	int i = 0, nCount = 0;
	CString szPlatform,szRegion, szAccount, szPassword;
	CArchive ar(&file, CArchive::load);
	ar >> nCount;
	while (i < nCount) {
		ar >> szPlatform >> szRegion >> szAccount ;
		m_list.InsertItem(i, L"0000");
		m_list.SetItemText(i, 9, szPlatform);
		m_list.SetItemText(i, 10, szRegion);
		m_list.SetItemText(i, 11, szAccount);
		++i;
	}
	//file.Close();
}
void CMFCCefDlg::Save() {
	CFile file;
	if (!file.Open(L"./data/account.data", CFile::modeCreate | CFile::modeWrite)) {
		//AfxMessageBox(L"保存配置时出错");
		return;
	}
	CArchive ar(&file, CArchive::store);
	int i = 0, nCount = m_list.GetItemCount();
	ar << nCount;
	while (i < nCount) {
		CString szPlatform = m_list.GetItemText(i, 9);
		CString szRegion = m_list.GetItemText(i, 10);
		CString szAccount = m_list.GetItemText(i, 11);
		ar << szPlatform << szRegion << szAccount;
		++i;
	}
	//file.Close();
}

void CMFCCefDlg::OnDestroy()
{
	CDialogEx::OnDestroy();	
	CRect rect;
	GetWindowRect(rect);	
	Save();
	// TODO: 在此处添加消息处理程序代码
}


void CMFCCefDlg::OnBnClickedButtonAddAccount()
{
	// TODO: 在此添加控件通知处理程序代码
	CDlgAddAccount dlg;
	if (IDCANCEL == dlg.DoModal()) {
		return;
	}

	// m_list.InsertColumn(9, _T("平台"), LVCFMT_CENTER, 80);
	// m_list.InsertColumn(10, _T("区服"), LVCFMT_CENTER, 40);
	// m_list.InsertColumn(11, _T("帐号"), LVCFMT_CENTER, 120);

	if (!CheckAccount(dlg.m_val_account)) {
		AfxMessageBox(L"帐号重复");
		return;
	}
	int nCount = m_list.GetItemCount();		
	CString platFormUrl = GetPlatfrom(dlg.m_val_platform);
	if (platFormUrl == "") {
		AfxMessageBox(L"指定的平台不存在");
		return;
	}
	CWinApp* pApp = AfxGetApp();
	pApp->WriteProfileStringW(L"account", dlg.m_val_account, dlg.m_val_password);	
	m_list.InsertItem(nCount, L"0000");
	m_list.SetItemText(nCount, 9, dlg.m_val_platform);
	m_list.SetItemText(nCount, 10, dlg.m_val_region);
	m_list.SetItemText(nCount, 11, dlg.m_val_account);

}
bool CheckPlatfromEx(CString szPlatformKey) {
	if (g_main_cwnd->GetPlatfrom(szPlatformKey) == L"") {
		return false;
	}
	return true;
}
bool CheckAccountEx(CString szAccount) {
	return g_main_cwnd->CheckAccount(szAccount);
}
bool CMFCCefDlg::CheckAccount(CString szAccount) {
	bool result = true;
	int index = 0, nCount = m_list.GetItemCount();
	while (index < nCount) {
		if (m_list.GetItemText(index, 11) == szAccount) {
			result = false;			
		}
		++index;
	}
	return result;
}
CString CMFCCefDlg::GetPlatfrom(CString szPlatformKey) {
	CWinApp* pApp = AfxGetApp();
	return pApp->GetProfileStringW(L"platfrom", szPlatformKey);
}
CString CMFCCefDlg::GetAccountPwd(CString szAccount) {
	CWinApp* pApp = AfxGetApp();	
	return pApp->GetProfileStringW(L"account", szAccount);
}
void CMFCCefDlg::OnBnClickedButtonAddPlatform()
{
	// TODO: 在此添加控件通知处理程序代码
	CDlgPlatform dlg;
	if (IDCANCEL == dlg.DoModal()) {
		return;
	}	
	CWinApp* pApp =  AfxGetApp();
	pApp->WriteProfileStringW(L"platfrom", dlg.m_val_platform, dlg.m_val_platform_url);
}


void CMFCCefDlg::OnBnClickedButtonStartSel()
{
	// TODO: 在此添加控件通知处理程序代码
}

long CMFCCefDlg::GetListIndex(long index)
{
	long item_count = m_list.GetItemCount();
	if (item_count == 0)
	{
		return -1;
	}

	if (index < 0 || index >= MAX_HWND * 2)
	{
		return -1;
	}

	if (index >= MAX_HWND)
	{
		index = index - MAX_HWND;
	}

	for (int i = 0; i < item_count; ++i)
	{
		long index_tmp = _tstoi(m_list.GetItemText(i, 2));

		if (index == index_tmp)
		{
			return i;
		}
	}
	return -1;
}


CString CMFCCefDlg::ThreadStateToString(ThreadState state)
{
	CString ret;

	switch (state)
	{
	case State_Inactive:
		ret = _T("未启动");
		break;
	case State_Starting:
		ret = _T("正在启动..");
		break;
	case State_Runing:
		ret = _T("正在运行");
		break;
	case State_Pausing:
		ret = _T("正在暂停");
		break;
	case State_Pause:
		ret = _T("暂停");
		break;
	case State_Resuming:
		ret = _T("正在恢复");
		break;
	case State_Stoping:
		ret = _T("正在停止");
		break;
	default:
		Log(_T("未定义的线程状态:%d"), state);
		break;
	}


	return ret;
}
void CMFCCefDlg::UpdateAction(long index, CString msg) {
	m_list.SetItemText(index, 8, msg);
}
void CMFCCefDlg::UpdateList(long index, long action)
{
	if (action == UI_ADD)
	{
		//long list_index = m_list.InsertItem(m_list.GetItemCount(), _T(""));
		long list_index = index;
		CString tmp;

		tmp.Format(_T("%d"), g_info[index].hwnd);
		m_list.SetItemText(list_index, 0, tmp);

		tmp.Format(_T("%d"), g_info[index].pid);
		m_list.SetItemText(list_index, 1, tmp);

		tmp.Format(_T("%d"), index);
		m_list.SetItemText(list_index, 2, tmp);

		tmp.Format(_T("%d"), index + MAX_HWND);
		m_list.SetItemText(list_index, 3, tmp);

		UpdateUI(index, UI_UPDATE);
		return;
	}
	else if (action == UI_DELETE)
	{
		long list_index = GetListIndex(index);

		if (list_index == -1)
		{
			return;
		}

		//m_list.DeleteItem(list_index);
		m_list.Invalidate();
		m_list.UpdateWindow();
		return;
	}
	else if (action == UI_UPDATE)
	{
		long list_index = GetListIndex(index);

		if (list_index == -1)
		{
			return;
		}

		// 先更新主
		m_list.SetItemText(list_index, 4, ThreadStateToString(g_info[index].thread_state));
		m_list.SetItemText(list_index, 6, g_info[index].task_state);
		// 再更新副
		m_list.SetItemText(list_index, 5, ThreadStateToString(g_info[index + MAX_HWND].thread_state));
		m_list.SetItemText(list_index, 7, g_info[index + MAX_HWND].excep_state);
		m_list.Invalidate();
		m_list.UpdateWindow();
		return;
	}
}

LRESULT CMFCCefDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	if (message == WM_NOTIFY_UI)
	{
		long list_index = GetListIndex((long)lParam);

		if (list_index >= 0)
		{
			long notify_code = (long)wParam;
			long index = (long)lParam;

			if (index >= MAX_HWND)
			{
				index = index - MAX_HWND;
			}

			switch (notify_code)
			{
			case NOTIFY_UPDATE:
				UpdateUI(index, UI_UPDATE);
				break;
			case NOTIFY_STOP:
				ThreadStop(index);
				break;
			case NOTIFY_RESTART:
				ThreadRestart(index);
				break;
			default:
				break;
			}
		}
		else
		{
			Log(_T("索引找不到 序号:%d"), lParam);
		}
	}
	else if (message == WM_CLOSE)
	{
		OnBnClickedButtonStopall();
		OnBnClickedButtonCloseallwin();
	}

	return CDialog::WindowProc(message, wParam, lParam);
}
void CMFCCefDlg::OnBnClickedButtonCloseallwin()
{
	// TODO: 在此添加控件通知处理程序代码
	CString hwnds = g_dm->EnumWindowByProcess(_T("notepad.exe"), _T("无标题 - 记事本"), _T(""), 1 + 8 + 16 + 32);
	if (hwnds.GetLength() == 0)
	{
		Log(_T("枚举窗口失败"));
		return;
	}

	CStringArray hwnd_array;
	long count = SplitString(hwnds, _T(","), hwnd_array, FALSE);

	for (int i = 0; i < count; ++i)
	{
		long hwnd = _tstoi(hwnd_array[i]);
		g_dm->TerminateProcess(g_dm->GetWindowProcessId(hwnd));
	}
}

void CMFCCefDlg::OnBnClickedButtonStopall()
{
	// TODO: 在此添加控件通知处理程序代码
	// TODO: 在此添加控件通知处理程序代码
	long item_count = m_list.GetItemCount();

	if (item_count == 0)
	{
		Log(_T("没有窗口"));
		return;
	}

	// 先全部设置结束标记,这样可加快结束的速度
	for (int i = 0; i < item_count; ++i)
	{
		long index = _tstoi(m_list.GetItemText(i, 2));
		ThreadSetExitState(index);
	}

	// 这里我们从最后一个开始，因为结束时，会删除表项
	long list_index = item_count - 1;
	while (list_index >= 0)
	{
		long index = _tstoi(m_list.GetItemText(list_index, 2));
		ThreadStop(index);
		--list_index;
	}
}


void CMFCCefDlg::OnBnClickedButtonPauseall()
{
	// TODO: 在此添加控件通知处理程序代码
		// TODO: 在此添加控件通知处理程序代码
	long item_count = m_list.GetItemCount();

	if (item_count == 0)
	{
		Log(_T("没有窗口"));
		return;
	}


	long list_index = item_count - 1;
	while (list_index >= 0)
	{
		long index = _tstoi(m_list.GetItemText(list_index, 2));
		ThreadPause(index);
		--list_index;
	}
}


void CMFCCefDlg::OnBnClickedButtonResumeall()
{
	// TODO: 在此添加控件通知处理程序代码
	long item_count = m_list.GetItemCount();

	if (item_count == 0)
	{
		Log(_T("没有窗口"));
		return;
	}


	long list_index = item_count - 1;
	while (list_index >= 0)
	{
		long index = _tstoi(m_list.GetItemText(list_index, 2));
		ThreadResume(index);
		--list_index;
	}
}


void CMFCCefDlg::OnBnClickedButtonPause()
{
	// TODO: 在此添加控件通知处理程序代码
	// TODO: 在此添加控件通知处理程序代码
	POSITION pos = m_list.GetFirstSelectedItemPosition();
	if (pos == NULL)
	{
		Log(_T("没有选择窗口"));
		return;
	}

	long list_index = (long)m_list.GetNextSelectedItem(pos);
	long index = _tstoi(m_list.GetItemText(list_index, 2));
	ThreadPause(index);
}


void CMFCCefDlg::OnBnClickedButtonStop()
{
	// TODO: 在此添加控件通知处理程序代码
	POSITION pos = m_list.GetFirstSelectedItemPosition();
	if (pos == NULL)
	{
		Log(_T("没有选择窗口"));
		return;
	}

	long list_index = (long)m_list.GetNextSelectedItem(pos);
	long index = _tstoi(m_list.GetItemText(list_index, 2));
	ThreadStop(index);
}


void CMFCCefDlg::OnBnClickedButtonResume()
{
	// TODO: 在此添加控件通知处理程序代码
	POSITION pos = m_list.GetFirstSelectedItemPosition();
	if (pos == NULL)
	{
		Log(_T("没有选择窗口"));
		return;
	}

	long list_index = (long)m_list.GetNextSelectedItem(pos);
	long index = _tstoi(m_list.GetItemText(list_index, 2));
	ThreadResume(index);
}


void CMFCCefDlg::OnBnClickedButtonRestart()
{
	// TODO: 在此添加控件通知处理程序代码
	POSITION pos = m_list.GetFirstSelectedItemPosition();
	if (pos == NULL)
	{
		Log(_T("没有选择窗口"));
		return;
	}

	long list_index = (long)m_list.GetNextSelectedItem(pos);
	long pid = _tstoi(m_list.GetItemText(list_index, 1));
	long index = _tstoi(m_list.GetItemText(list_index, 2));
	if (ThreadRestart(index) == FALSE)
	{
		g_dm->TerminateProcess(pid);
	}
}


void CMFCCefDlg::OnBnClickedButtonStartall()
{
	// TODO: 在此添加控件通知处理程序代码
	POSITION pos = m_list.GetFirstSelectedItemPosition();
	if (pos == NULL)
	{
		Log(_T("没有选择窗口"));
		return;
	}
	int idx = m_list.GetNextSelectedItem(pos);
	while (idx != -1) {
		//CString szTitle = GetListTitle(idx);
		//HWND selHwnd = ::FindWindow(NULL, szTitle);
		CString gHwnd = m_list.GetItemText(idx, 0);
		long hwnd = _tstoi(gHwnd);

		//if ((long)selHwnd != hwnd) {
		hwnd = g_dm->GetWindow(hwnd, 1);
		hwnd = g_dm->GetWindow(hwnd, 1);
		hwnd = g_dm->GetWindow(hwnd, 1);
		//}		
		if (!ThreadStart(idx, hwnd))
		{
			g_dm->TerminateProcess(g_dm->GetWindowProcessId(hwnd));
		}
		idx = m_list.GetNextSelectedItem(pos);
	}
}
